package com.rightsidetech.http.aspect;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.rightsidetech.commom.enums.CodeIdEnum;
import com.rightsidetech.commom.enums.ModifyName;
import com.rightsidetech.commom.exception.BizException;
import com.rightsidetech.commom.utils.RedisUtils;
import com.rightsidetech.mall.dto.log.CommodityMarketName;
import com.rightsidetech.mall.dto.log.MallLogInfoDto;
import com.rightsidetech.mall.dto.request.*;
import com.rightsidetech.mall.entity.MallBaseInfo;
import com.rightsidetech.mall.entity.MallCommodityWithBLOBs;
import com.rightsidetech.mall.entity.MallIntegralCommodity;
import com.rightsidetech.mall.service.MallBaseInfoService;
import com.rightsidetech.mall.service.MallCommodityService;
import com.rightsidetech.mall.service.MallIntegralCommodityService;
import com.rightsidetech.system.entity.SysUserLoginInfo;
import com.rightsidetech.system.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Map;
import java.util.stream.Collectors;

@Aspect
@Component
@Slf4j
public class MallLogAspect {

    @Autowired
    private RedisUtils redisUtils;
    @Resource
    private SysUserService sysUserService;
    @Resource
    private MallBaseInfoService mallBaseInfoService;
    @Resource
    private MallCommodityService mallCommodityService;
    @Resource
    private MallIntegralCommodityService mallIntegralCommodityService;

    @Around("@annotation(mallLog)")
    public Object doAround(ProceedingJoinPoint pjp, MallLog mallLog) throws Throwable {
        return mallLogSave(pjp, mallLog);
    }

    private Object mallLogSave(ProceedingJoinPoint pjp, MallLog mallLog) throws Throwable {
        Object result = null;
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String uri = request.getRequestURI();
        //方法参数
        Object[] args = pjp.getArgs();
        String token = request.getHeader("token_admin");
        if (StrUtil.isBlank(token)) {
            throw new BizException(CodeIdEnum.Expired);
        }
        Long loginInfoId = sysUserService.sysUsercheckToken(token);
        if (ObjectUtil.isEmpty(loginInfoId)) {
            throw new BizException(CodeIdEnum.Expired);
        }
        MallLogInfoDto dto = new MallLogInfoDto();
        dto.setLoginInfoId(loginInfoId);
        dto.setUrl(uri);
        SysUserLoginInfo sysUserLoginInfo = sysUserService.selectUserById(loginInfoId);
        dto.setLoginName(ObjectUtil.isEmpty(sysUserLoginInfo) ? null : sysUserLoginInfo.getLoginName());
        dto.setCommodityMarketName(mallLog.marketName().getMallType());
        dto.setParam(args[0]);
        if(mallLog.modifyType().equals(ModifyName.SAVE)){
            //添加操作
            dto.setOperateType("新增");
            if(mallLog.marketName().equals(CommodityMarketName.BATTERY_MALL)) {
                CommoditySaveReq req = (CommoditySaveReq) args[0];
                if (ObjectUtil.isNotEmpty(req.getMallBaseId())) {
                    MallBaseInfo info = mallBaseInfoService.selectByPrimaryKey(req.getMallBaseId());
                    if (ObjectUtil.isNotEmpty(info)) {
                        dto.setNewParam(info.getCommodityName());
                        dto.setCommodityName(info.getCommodityName());
                    }
                }
            }else if(mallLog.marketName().equals(CommodityMarketName.INTEGRAL_MALL)){
                IntegralSaveReq req = (IntegralSaveReq) args[0];
                if (ObjectUtil.isNotEmpty(req.getMallBaseId())) {
                    MallBaseInfo info = mallBaseInfoService.selectByPrimaryKey(req.getMallBaseId());
                    if (ObjectUtil.isNotEmpty(info)) {
                        DetailSpecsReq specs = req.getSpecs();
                        dto.setCommodityName(info.getCommodityName());
                        StringBuilder builder = new StringBuilder();
                        builder.append(info.getCommodityName());
                        String newParam = null;
                        if(ObjectUtil.isNotEmpty(specs)){
                            String collect = specs.getValueList().stream().map(DetailSpecsValueReq::getSpecsValue).collect(Collectors.joining("、"));
                            newParam = builder.append(" (").append(collect).append(")").toString();
                        }else {
                            newParam = info.getCommodityName();
                        }
                        dto.setNewParam(newParam);
                    }
                }
            }
        }else if(mallLog.modifyType().equals(ModifyName.GROUNDING)){
            //上下架
            CommodityIsGroundingReq req = (CommodityIsGroundingReq)args[0];
            if(mallLog.marketName().equals(CommodityMarketName.BATTERY_MALL)){
                MallCommodityWithBLOBs commodity = mallCommodityService.selectByPrimaryKey(req.getId());
                if(ObjectUtil.isNotEmpty(commodity)){
                    dto.setNewParam(commodity.getCommodityName());
                    dto.setCommodityName(commodity.getCommodityName());
                    if(req.getStatus() != null && req.getStatus() == 1){
                        dto.setOperateType("上架");
                    }else {
                        dto.setOperateType("下架");
                    }
                }
            }else if(mallLog.marketName().equals(CommodityMarketName.INTEGRAL_MALL)){
                MallIntegralCommodity commodity = mallIntegralCommodityService.selectByPrimaryKey(req.getId());
                if(ObjectUtil.isNotEmpty(commodity)){
                     StringBuilder builder = new StringBuilder().append(commodity.getCommodityName());
                       if(commodity.getSpecs() != null){
                           builder.append(" (").append(commodity.getSpecs() == null ? "" : commodity.getSpecs()).append(")").toString();
                       }
                    String newParam = builder.toString();
                    dto.setNewParam(newParam);
                    dto.setCommodityName(commodity.getCommodityName());
                    if(req.getStatus() != null && req.getStatus() == 1){
                        dto.setOperateType("上架");
                    }else {
                        dto.setOperateType("下架");
                    }
                }
            }
        }else if(mallLog.modifyType().equals(ModifyName.POPULAR)){
            CommodityPopularReq req = (CommodityPopularReq) args[0];
            if(mallLog.marketName().equals(CommodityMarketName.BATTERY_MALL)){
                MallCommodityWithBLOBs commodity = mallCommodityService.selectByPrimaryKey(req.getId());
                if(ObjectUtil.isNotEmpty(commodity)){
                    dto.setNewParam(commodity.getCommodityName());
                    dto.setCommodityName(commodity.getCommodityName());
                    if(req.getIsPopular() != null && req.getIsPopular() == 1){
                        dto.setOperateType("爆款");
                    }else {
                        dto.setOperateType("取消爆款");
                    }
                }
            }else if(mallLog.marketName().equals(CommodityMarketName.INTEGRAL_MALL)) {
                MallIntegralCommodity commodity = mallIntegralCommodityService.selectByPrimaryKey(req.getId());
                if(ObjectUtil.isNotEmpty(commodity)){
//                    String newParam = new StringBuilder().append(commodity.getCommodityName()).toString();
//                    if(commodity.getSpecs()!=null){
//                        newParam = new StringBuilder().append(commodity.getCommodityName()).append(" (").append(commodity.getSpecs()).append(")").toString();
//                    }
                    String newParam = new StringBuilder().append(commodity.getCommodityName()).append(commodity.getSpecs()==null? "": '('+commodity.getSpecs()+')').toString();
                    dto.setNewParam(newParam);
                    dto.setCommodityName(commodity.getCommodityName());
                    if(req.getIsPopular() != null && req.getIsPopular() == 1){
                        dto.setOperateType("爆款");
                    }else {
                        dto.setOperateType("取消爆款");
                    }
                }
            }
        }else if(mallLog.modifyType().equals(ModifyName.UPDATE)){
            dto.setOperateType("编辑");
            if(mallLog.marketName().equals(CommodityMarketName.BATTERY_MALL)){
                CommodityUpReq req = (CommodityUpReq) args[0];
                MallCommodityWithBLOBs commodity = mallCommodityService.selectByPrimaryKey(req.getId());
                if(ObjectUtil.isNotEmpty(commodity)){
                    dto.setCommodityName(commodity.getCommodityName());
                    dto.setNewParam(req);
                    dto.setOldParam(commodity);
                }
            }else if(mallLog.marketName().equals(CommodityMarketName.INTEGRAL_MALL)){
                IntegralUpReq req = (IntegralUpReq) args[0];
                MallIntegralCommodity integralCommodity = mallIntegralCommodityService.selectByPrimaryKey(req.getId());
                if(ObjectUtil.isNotEmpty(integralCommodity)){
                    dto.setCommodityName(integralCommodity.getCommodityName());
                    dto.setNewParam(req);
                    dto.setOldParam(integralCommodity);
                }
            }
        }
        dto.setCreatedAt(DateUtil.format(new Date(),"yyyy-MM-dd HH:mm:ss"));
        //接口方法调用
        result = pjp.proceed();
        Map<String, Object> map = BeanUtil.beanToMap(result);
        if (map.get("codeId") == null || !"1".equals(String.valueOf(map.get("codeId")))) {
            return result;
        }
        redisUtils.publish("MALL_LOG", JSONUtil.toJsonStr(dto));
        return result;
    }


}
